void Main() { var measurements = File.ReadAllLines(Path.Combine(Path.GetDirectoryName (Util.CurrentQueryPath),"..","day13.txt")).Select(s => { var m = Regex.Match(s, @"([^ ]+) would (gain|lose) (\d+) .* ([^ ]+)\."); return new Measurement { Person = m.Groups[1].Value, Adjacent = m.Groups[4].Value, HappinessUnits = int.Parse(m.Groups[3].Value) * (m.Groups[2].Value == "lose" ? -1 : 1) }; }).ToList(); // part 1 CalculateHappiness(measurements).Dump(); // part 2 measurements.AddRange(measurements.Select(m => m.Person).Distinct().SelectMany(p => new [] { new Measurement { Person = "Me", Adjacent = p, HappinessUnits = 0 }, new Measurement { Person = p, Adjacent="Me" , HappinessUnits = 0}}).ToList()); CalculateHappiness(measurements).Dump(); } int CalculateHappiness(List measurements) { var possibilities = Permutations(measurements.Select(m => m.Person).Distinct().ToList()).ToList(); var happiness = possibilities.Select(p => p.ToArray()).Select(p => { var score = 0; for (var pos = 0; pos < p.Length; pos ++) { score += measurements.First (m => m.Person == p[pos] && m.Adjacent == p[(pos+1 < p.Length) ? pos + 1 : 0]).HappinessUnits; score += measurements.First (m => m.Person == p[pos] && m.Adjacent == p[(pos > 0) ? pos - 1 : p.Length-1]).HappinessUnits; } return score; }); return happiness.OrderByDescending(s => s).First (); } public class Measurement { public string Person { get; set; } public int HappinessUnits { get; set; } public string Adjacent { get; set; } } IEnumerable> Permutations(IEnumerable list, int length = 0) { if (length == 0) length = list.Count(); if (length == 1) return list.Select(t => new T[] { t }); return Permutations(list, length - 1) .SelectMany(t => list.Where(e => !t.Contains(e)), (t1, t2) => t1.Concat(new T[] { t2 })); }